﻿using _1_31_2015_SLMSite.Data;
using _1_31_2015_SLMSite.Data.Models;
using _1_31_2015_SLMSite.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace _1_31_2015_SLMSite.Controllers
{
    public class UserController : Controller
    {
        private static List<string> HydrateUserTypes()
        {
            List<string> types = new List<string>()
            {
                "Admin",
                "General",
                "Client"
            };

            return types;
        }

        // Return list of users  based on role passed in
        private static List<UserViewModel> HydrateUsersByRole(string role)
        {
            List<UserViewModel> users = new List<UserViewModel>();
            using (ApplicationDbContext db = new ApplicationDbContext())
            {
                List<ApplicationUser> allUsers = db.Users.ToList();
                UserStore<ApplicationUser> userStore = new UserStore<ApplicationUser>(db);
                UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(userStore);

                foreach (ApplicationUser u in allUsers)
                {
                    string userRole = userManager.IsInRole(u.Id, "Admin") ? "Admin" : userManager.IsInRole(u.Id, "Client") ? "Client" : "General";
                    if (userRole == role || role == "All")
                    {
                        UserViewModel user = new UserViewModel();
                        user.LastName = u.LastName;
                        user.FirstName = u.FirstName;
                        user.Email = u.Email;
                        user.UserId = u.Id;
                        user.DisplayName = u.DisplayName;
                        user.Role = userRole;
                        users.Add(user);
                    }

                }
                return users;
            }
        }

        public List<UserViewModel> GetUsersByRole(string role)
        {
            List<UserViewModel> models = new List<UserViewModel>();
            models = HydrateUsersByRole(role);

            return models;
        }

        public string GetUserRole(string userId)
        {
            string userRole = null;
            UserViewModel user = GetUserById(userId);
            if (user != null)
            {
                using (ApplicationDbContext db = new ApplicationDbContext())
                {
                    UserStore<ApplicationUser> userStore = new UserStore<ApplicationUser>(db);
                    UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(userStore);
                    userRole = user.Role = userManager.IsInRole(user.UserId, "Admin") ? "Admin" : userManager.IsInRole(user.UserId, "Technician") ? "Technician" : "General";
                }
            }

            return userRole;
        }

        // If userId is null, this is being called with the intention of creating a tech
        public UserViewModel GetUserById(string userId="")
        {
            UserViewModel model = new UserViewModel();
            if (userId != "")
            {
                using (ApplicationDbContext db = new ApplicationDbContext())
                {
                    ApplicationUser user = db.Users.FirstOrDefault(u => u.Id == userId);
                    if(user != null)
                    {
                        UserStore<ApplicationUser> userStore = new UserStore<ApplicationUser>(db);
                        UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(userStore);

                        model.FirstName = user.FirstName;
                        model.LastName = user.LastName;
                        model.Email = user.Email;
                        model.DisplayName = user.DisplayName;
                        model.ImgUrl = user.ImgUrl;
                        model.UserId = user.Id;
                        model.Role = userManager.IsInRole(userId, "Admin") ? "Admin" : userManager.IsInRole(userId, "Client") ? "Client" : "General";
                    }
                   
                }
            }
            model.Roles = HydrateUserTypes();
            return model;
        }

        // This is used to update/add user, the only differenct is that if it is a create, the userName will be null
        public string AddUpdateUser(UserViewModel model, string userId)
        {
            string message = "";
            using (ApplicationDbContext db = new ApplicationDbContext())
            {
                UserStore<ApplicationUser> userStore = new UserStore<ApplicationUser>(db);
                UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(userStore);
                ApplicationUser user = null;
                if (userId != null) // userName passed in so update existing user
                {
                    user = db.Users.FirstOrDefault(u => u.Id == userId);
                    user.FirstName = model.FirstName;
                    user.LastName = model.LastName;
                    user.Email = model.Email;
                    user.DisplayName = model.DisplayName;
                    user.ImgUrl = model.ImgUrl;

                    // Find the current role the user is in, and if it is different than the role coming in remove from role and add in corret role
                    string role = userManager.IsInRole(user.Id, "Admin") ? "Admin" : userManager.IsInRole(user.Id, "Client") ? "Client" : "General";
                    if (role != model.Role)
                    {
                        userManager.RemoveFromRole(user.Id, role);
                        userManager.AddToRole(user.Id, model.Role);
                    }

                    message = "EditOk";
                }
                else // userName is null - create new user
                {

                    user = new ApplicationUser()
                    {
                        FirstName = model.FirstName,
                        LastName = model.LastName,
                        UserName = model.Email,
                        Email = model.Email
                    };

                    userManager.Create(user, "123456");
                    userManager.AddToRole(user.Id, model.Role);
                    user = userManager.FindByName(user.UserName);

                    message = "NewOk";

                }
                try
                {
                    db.SaveChanges();

                }
                catch (Exception ex)
                {

                    message = "An error occured while adding/updating a user (" + model.FirstName + " " + model.LastName + ") => " + ex.Message;
                }

            }
            return message;
        }

        // Need to make sure to remove user from communications/appointment
        public string DeleteUser(string userId)
        {

            using (ApplicationDbContext db = new ApplicationDbContext())
            {
                UserStore<ApplicationUser> userStore = new UserStore<ApplicationUser>(db);
                UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(userStore);
                ApplicationUser user = db.Users.FirstOrDefault(u => u.Id == userId);
                if (user != null)
                {
                    //// if user has reported issues, do not delete them
                    //List<IssueViewModel> issues = GetUserReportedIssues(userId);
                    //if (issues.Count == 0)
                    //{
                    //    string role = userManager.IsInRole(user.Id, "Admin") ? "Admin" : userManager.IsInRole(user.Id, "Client") ? "Client" : "General";
                    //    // If user is admin or technician, may have assignments - remove the assignments
                    //    if (role == "Admin" || role == "Technician")
                    //    {
                    //        List<Assignment> assignments = db.Assignments.Where(a => a.UserId == userId).Select(a => a).ToList();
                    //        foreach (Assignment assignment in assignments)
                    //        {
                    //            //before removing assignment, see how many techs are assigned to this, if this user is only one set is assigned to false
                    //            List<AdmUserSelectionModel> techs = HydrateAssignedTechs(assignment.IssueId);
                    //            if (techs.Count <= 1)
                    //            {
                    //                assignment.Issue.IsAssigned = false;
                    //            }
                    //            db.Assignments.Remove(assignment);
                    //        }
                    //    }

                        string role = userManager.IsInRole(user.Id, "Admin") ? "Admin" : userManager.IsInRole(user.Id, "Client") ? "Client" : "General";
                        userManager.RemoveFromRole(user.Id, role);
                        userManager.Delete(user);
                    //}
                }

                try
                {
                    db.SaveChanges();
                    return "ok";
                }
                catch (Exception ex)
                {

                    return "An error occured while deleting user (" + userId + "), => " + ex.Message;
                }

            }


        }



/* --------------------------------------------------------------------- */

        // GET: User
        public ActionResult Index()
        {
            UsersListsViewModel model = new UsersListsViewModel();
            model.Admins = HydrateUsersByRole("Admin");
            model.Clients = HydrateUsersByRole("Client");
            model.Generals = HydrateUsersByRole("General");           
            
            return View(model);
        }


        public ActionResult AddUpdate(string userId="")
        {
            UserViewModel model = GetUserById(userId);

            return View(model);
        }

        [HttpPost]
        // This is used to update/add technician, the only differenct is that if it is a create, the userName will be null
        public ActionResult AddUpdate(UserViewModel model, string userId)
        {
            string result = AddUpdateUser(model, userId);
            //if (result == "NewOk")
            //{
            //    TimeLineHelper.UserOperations(model.FirstName + model.LastName, User.Identity.Name, TimeLineHelper.Operations.New);
            //}
            //else if (result == "EditOk")
            //{
            //    TimeLineHelper.UserOperations(model.FirstName + model.LastName, User.Identity.Name, TimeLineHelper.Operations.Edit);

            //}
            //else
            //{
            //    TimeLineHelper.ErrorOperations(User.Identity.Name, TimeLineHelper.Operations.Edit, result);

            //}

            //return RedirectToAction("Users", new { role = model.Role });
            UserViewModel updatedModel = GetUserById(userId);
            return View(updatedModel);
        }

 
        public ActionResult Delete(string userId)
        {
            string result = DeleteUser(userId);

            return RedirectToAction("Index");
        }





    }
}